#include "RecursoDeAlmacenamientoIndexado.h"
#include "../indices/Indice.h"
#include "../estrategiaAlmacenamiento/EstrategiaAlmacenamiento.h"

RecursoDeAlmacenamientoIndexado::RecursoDeAlmacenamientoIndexado(
		EstrategiaAlmacenamiento* estrategiaAlmacenamiento,
		EstrategiaRecurso* estrategiaRecurso, Indice* indice) :
	RecursoDeAlmacenamiento(estrategiaAlmacenamiento, estrategiaRecurso) {

	this->indice = indice;

}

RecursoDeAlmacenamientoIndexado::~RecursoDeAlmacenamientoIndexado() {
	delete this->indice;
}

Bytes RecursoDeAlmacenamientoIndexado::cargar(Key clave) {

	TipoClave* extractor = indice->getExtractor();
	offset numeroComponente = 0;

	bool exito = indice->getNumComponente(clave, numeroComponente);

	if (!exito) {
		return Bytes("");
	}

	return estrategiaAlmacenamiento->obtener(numeroComponente, clave, extractor);
}

bool RecursoDeAlmacenamientoIndexado::guardar(Bytes dato) {
	TipoClave* extractor = indice->getExtractor();
	long numeroComponente = -1;
	Key clave = extractor->crearClave(extractor->extraerClave(dato));
	if (!indice->existeClave(clave)) {
		estrategiaAlmacenamiento->guardar(dato, numeroComponente);
		indice->agregar(clave, numeroComponente);
		return true;
	}
	return false;

}

bool RecursoDeAlmacenamientoIndexado::eliminar(Key clave) {

	TipoClave* extractor = indice->getExtractor();
	offset numeroComponente;

	bool exito = indice->quitar(clave, numeroComponente);

	if (!exito) {
		return false;
	}

	return estrategiaAlmacenamiento->eliminar(numeroComponente, clave,
			extractor);
}

void RecursoDeAlmacenamientoIndexado::inicializar() {
	RecursoDeAlmacenamiento::inicializar();
}

bool RecursoDeAlmacenamientoIndexado::modificar(Bytes dato) {

	TipoClave* extractor = indice->getExtractor();
	Key clave = extractor->crearClave(extractor->extraerClave(dato));
	if (indice->existeClave(clave)) {

		offset numeroComponenteViejo;
		indice->quitar(clave,numeroComponenteViejo);
		estrategiaAlmacenamiento->eliminar(numeroComponenteViejo,clave,extractor);

		long numeroComponente = -1;
		estrategiaAlmacenamiento->guardar(dato,numeroComponente);
		indice->agregar(clave, numeroComponente);
		return true;
	}
	return false;
}

Indice* RecursoDeAlmacenamientoIndexado::getIndice() {
	return this->indice;
}
